from sympy.sets import FiniteSet,Set
from sympy.core import Equality,Expr,Symbol
from sympy.solvers import solve_univariate_inequality
from typing import Union
from sympy.core.symbol import _symbol
from sympy import S,conjugate,nonlinsolve,Reals,I
from sympy.core.relational import Relational

def set_relation_solve():
    pass


def solve_univariate_inequalities(
    inequal_list: list[Relational], univariate: Symbol, domain: Set = Reals
) -> Set:
    """This function's goal is to solve the group of univariate unequalities.

    Parameters
    ==========

    inequal_list : list of Relationals
    univariate : Symbol of the univariate
    domain : Set of Interval

    Return
    ======

    solve_univariate_inequalities : Set of Interval

    See Also
    ========

    solve_univariate_inequality

    Examples
    ========

    >>> from sympy import *
    >>> x=symbols("x",real=True)
    >>> neq1 = 2 < x
    >>> neq2 = x < 8
    >>> solve_univariate_inequalities([neq1,neq2],x)
    Interval.open(2, 8)
    >>> neq3 = x**3 >= 4
    >>> solve_univariate_inequalities([neq3,neq2],x)
    Interval.Ropen(2**(2/3), 8)


    """
    for inequal in inequal_list:
        domain = solve_univariate_inequality(inequal, univariate, False, domain)
    return domain


def solve_complex(expr: Union[Expr, Equality], z: Symbol) -> Set:
    """It will change the complex univariate to `a+b*I`,then solve the functions of `a,b` to solve the complex function.

    Parameters
    ==========

    expr : Equality or Expr
    z : Symbol of Complexes

    Return
    ======

    solve_complex : Set

    Examples
    ========

    >>> from sympy import *
    >>> z = symbols("z",complex = True)
    >>> eq = Eq(z**2-conjugate(z),3)
    >>> solve_complex(eq,z)
    {1/2 - sqrt(13)/2, 1/2 + sqrt(13)/2}
    >>> expr = (z+conjugate(z))/(z-conjugate(z))-I
    >>> solve_complex(expr,z)
    {-b + I*b}
    """
    answer_list = []
    a = _symbol("a", real=True)
    b = _symbol("b", real=True)
    # TODO: 判断z是否为变量符号
    sub_z_dict = {z: a + b * I, conjugate(z): a - b * I}

    if isinstance(expr, Equality):
        expr = expr.lhs - expr.rhs
    expr_tuple = expr.subs(sub_z_dict).as_real_imag()
    answers = nonlinsolve(expr_tuple, [a, b], Reals)
    for answer in answers:
        if (answer[0] in Reals) and (answer[1] in Reals):
            answer_list.append(answer[0] + answer[1] * I)
    return FiniteSet(*answer_list)
